import { ref, onMounted, Ref, reactive } from 'vue';
import _ from 'lodash';
import { fabric } from "fabric";
import useToolBar from './useToolBar';
import useContentViewer from './useContentViewer';
import useFabric from './useFabric';
import useFabricTool from './useFabricTool';
import useContentLeftSlide from './useContentLeftSlide';
import { formComponentRead } from '@/api/projectDetail/projectDetail';
import { getAnnoArList, getInitSettingData, getInitResultData, saveCrListData, updateCrListData } from '@/api/readPathology/readPathology';
import { getLesionData as searchLesionData } from '@/api/setting/setting';
import { useRouter, useRoute } from 'vue-router';
import { useMarkLesionStore } from '@/store';
import type { IEvent, Object } from 'fabric/fabric-impl';
import * as Type from '@/api/readPathology/readPathology.d';
import * as Temp from './type.d';
import { getLocalStroage, getMarkCanvasObj } from './util';
import { Message } from '@arco-design/web-vue';
import OpenSeadragon from 'openseadragon';

export default function useContent(
    radioVisible: Ref<boolean>, 
    scrapValue: Ref<string>, 
    radioChecked: Ref<boolean | undefined>, 
    seriesSettings: Ref<Temp.ShowComponentObj>,
    findingVisible: Ref<boolean>,
    findingValue: Ref<string>,
    diagnosisVisible: Ref<boolean>,
    diagnosisValue: Ref<string>,
    markList: Ref<{
        id: number;
        name: string;
        label: string;
        type: string;
        nidusList: any[];
    }[]>,
    arListData: Ref<Type.ArItem[] | null>,
    currentItem: Ref<number>,
    showLesionList: Ref<Temp.NidusList[]>,
    currentSubmenuItem: Ref<string | number>,
    currentMiniSeriesSet: Ref<Temp.ShowComponentObj>,
) {

    // 设置当前新增标注返回的id值
    const alrId = ref<number>(0);

    // 获取路由进行相关操作
    const route = useRoute();

    // 获取存储对象
    const markLesionStore = useMarkLesionStore();

    // 图片预览容器
    const { viewerRef, viewer, options, slideInfo, mouseTracker, initViewer, getInfo } = useContentViewer();
    
    // 缩略图操作
    // 倍率条
    const multiplying = ref(40);
    // 倍率条根据倍率进行调整图片
    const handleMagnification = (currentMagn: number) => {
        viewer.value.viewport.zoomTo(currentMagn * getActualNum());
        // 根据病灶列表的数据清除当前画布标注
        window.frabicCanvas?.clear();
        // 重新执行查询数据
        getInitData();
    };
    // 比例尺
    // 鼠标位置
    const mouseString = ref('');
    const handleMouseMove = (e: any) => {
        const point = new OpenSeadragon.Point(e.x, e.y);
        const imgPoint = viewer.value?.viewport?.windowToImageCoordinates(point)!;
        mouseString.value = Math.round(imgPoint?.x * 100) / 100 + ',' + Math.round(imgPoint?.y * 100) / 100;
    }

    // 工具栏item点击操作
    const handleToolClick = (item: { id: number; }, value?: string | number | Record<string, any> | undefined) => {
        currentItem.value = item.id;
        // 通过标注工具集合查找当前点击的病灶项
        let filterObj: Temp.NidusItem = {
            id: '',
            name: '',
            lesion: '',
            eyeStatus: false,
            color: '',
            toolList: [],
            list: {
                formId: 0,
                form: {},
                formOptions: []
            }
        };
        markList.value.map(v => {
            filterObj = v.nidusList.filter(it => it.lesion === value)[0];
        });
        handleChangeToolViewer(filterObj);
    };

    // 调整容器配置的辅助工具函数
    const _handleChangeToolViewer = (num: number, levelFlag: boolean, verticalFlag: boolean) => {
        viewer.value.zoomPerScroll = num;
        viewer.value.panHorizontal = levelFlag;
        viewer.value.panVertical = verticalFlag;
    };

    let lesionResultData = reactive({
        dataList: <Type.LesionResultItem[]>[]
    });
    //  初始化获取结果用于相关工具栏，标注，病灶等数据回显
    const getInitData = async (type: boolean = false) => {
        console.log(window.frabicCanvas.calcOffset().viewportTransform, '接口');
        showLesionList.value = [];
        const params: Type.ReadParams = {
            arId: arListData.value! && arListData.value[0].id
        }
        console.log(window.frabicCanvas.calcOffset().viewportTransform, '接口调用前');
        const res = await getInitResultData(params);
        console.log(window.frabicCanvas.calcOffset().viewportTransform, '接口调用后');
        const { 
            id,
            yay = undefined, 
            seriesCompResultList = [],
            lesionResultList = []
        } = res?.data;
        // 阴阳性回显
        yay && (radioChecked.value = yay === 1 ? true : false);
        // 大征象数据回显
        getSeriesCompResultData(seriesCompResultList);
        // 检查所见数据回显
        findingValue.value = '';
        // 诊断所得数据回显
        diagnosisValue.value = '';
        // 病灶列表数据回显
        lesionResultList && (lesionResultData.dataList = _.cloneDeep(lesionResultList));
        lesionResultList && setTimeout(() => {getLesionData(lesionResultList, type)}, 500);
        // lesionResultList && getLesionData(lesionResultList, type);
    };

    // 如果是新增聚焦当前标注
    const getActiveObject = () => {
        // 标注画布鼠标按下，并且标注存在，并让标注聚焦病灶列表
        const currentItenMarkObj = showLesionList.value.filter(item => item.markInfo.id === alrId.value);
        if (currentItenMarkObj.length !== 0) {
            // 设置当前选择的id，将病灶列表聚焦到当前选择病灶
            currentSubmenuItem.value = currentItenMarkObj[0].disease.id;
            // 根据当前选择的病灶设置当前聚焦的小征象
            currentMiniSeriesSet.value = currentItenMarkObj[0].disease.list;
            window.frabicCanvas?.setActiveObject(currentItenMarkObj[0].markInfo);
        }
    }

    // 获得标注工具相关属性及事件
    const { 
        fabricToolContainer, 
        fabricToolCanvas, 
        fabricCanvas, 
        pencilColor, 
        pencilWidth, 
        initMarkTool, 
        resize, 
        resizeCanvas,
        linterMouseEvent
    } = useFabric(viewer, slideInfo, currentItem, showLesionList, alrId, arListData, mouseTracker, currentSubmenuItem, getInitData, currentMiniSeriesSet, lesionResultData);

    // 内容区左侧属性及操作
    const { 
        menuItemVisibile, 
        eyeAllVisibile, 
        // showLesionList,
        handleEyeClick, 
        handleAllEyeClick, 
        handleDelClick,
        handleColorChange,
    } = useContentLeftSlide(fabricToolCanvas, fabricCanvas, alrId, showLesionList, getInitData, lesionResultData, currentSubmenuItem);

    // 根据工具操作视图容器
    const handleChangeToolViewer = (currentItemObj?: Temp.NidusItem) => {
        switch (currentItem.value) {
            case 1:
                // 缩放
                viewer.value.setMouseNavEnabled(true);
                _handleChangeToolViewer(1.1, false, false);
                break;
            case 2:
                // 移动
                viewer.value.setMouseNavEnabled(true);
                _handleChangeToolViewer(1.1, true, true);
                break;
            case 3:
                // 重置
                viewer.value.setMouseNavEnabled(true);
                viewer.value.viewport.goHome(false);
                currentItem.value = 0;
                // 根据病灶列表的数据清除当前画布标注
                window.frabicCanvas?.clear();
                // 重新执行查询数据
                getInitData();
                break;
            case 5:
                // 删除尺子
                // 通过所有的对象找出type类型为line的对象并移除
                const markObjects = window.frabicCanvas?.getObjects().filter((item: { type: string; }) => item.type === 'group');
                markObjects?.map((item: Object) => window.frabicCanvas?.remove(item));
                localStorage.removeItem('markData');
                break;
            case 4:
            case 6:
            case 7:
                // 绘制尺子，矩形及椭圆
                viewer.value.setMouseNavEnabled(false);
                // 通过pinia存储当前对象
                if (currentItemObj && currentItemObj?.color !== '') {
                    markLesionStore.setCurrentItem(currentItemObj);
                }
                break;
            default:
                _handleChangeToolViewer(1.1, false, false);
                break;
        };
    };

    // 获取标注画的事件
    // const { doDrawing, mouseDown, mouseMove, mouseUp } = useFabricTool(fabricCanvas, viewer, pencilColor, pencilWidth, currentItem, nidusList, slideInfo);
    // const { doDrawing, mouseDown, mouseMove, mouseUp } = useFabricTool(fabricCanvas, viewer, pencilColor, pencilWidth, currentItem, showLesionList, slideInfo, alrId, arListData);
    
    // 初始获取相应倍率进行数值展示
    const initZoom = () => {
        viewer.value.addHandler('zoom', (options: { zoom: number; }) => {
            // 倍率条处理
            multiplying.value = Math.round((options.zoom / getActualNum()) * 10) / 10;
        });
    };

    // 获取实际比例
    const getActualNum = () => {
        const originImgWidth = Number(slideInfo.value.Width);
        const Magnification = Number(slideInfo.value.Magnification) || 20;
        const containerWidth = Number(viewer.value.container.clientWidth);
        return originImgWidth / Magnification / containerWidth;
    };

    // 大小征象操作的时候创建及更新征象数据操作
    const handleChange = async (value: any, item: Temp.FormOptionsItem, type: number, currentSubmenuItem?: string | number) => {
        if (item.parameter && item.parameter.isdefault) {
            // 为true调用变更征象接口
            const params = {
                arId: arListData.value! && arListData.value[0].id,
                alrId: 0,
                acrList: [
                    {
                        componentId: item.componentId,
                        result: ''
                    }
                ]
            }
            if (Array.isArray(value)) {
                const newValue = _.cloneDeep(value);
                if (item.type === 'checkbox' || item.type === 'child_select') {
                    params.acrList[0].result = newValue.length > 1 ? newValue.join('@#@') : newValue[0];
                } 
            } else {
                params.acrList[0].result = value;
            }
            if (type === 2 && currentSubmenuItem) {
                params.alrId = Number(currentSubmenuItem);
            }
            const res = await saveCrListData(params);
            const { acrList } = res.data;
            item.acrId = acrList[0].acrId;
            item.id = acrList[0].acrId;
            Message.success('新增成功！');
            // getInitData();
        } else {
            // 为false调用新增
            if (item.acrId && value) {
                if (Array.isArray(value)) {
                    const newValue = _.cloneDeep(value);
                    const params = {
                        acrId: item.acrId,
                        result: newValue.length > 1 ? newValue.join('@#@') : newValue[0]
                    }
                    const res = await updateCrListData(params);
                    Message.success('更新成功！');
                    // getInitData();
                } else {
                    const params = {
                        acrId: item.acrId,
                        result: value
                    }
                    const res = await updateCrListData(params);
                    Message.success('更新成功！');
                    // getInitData();
                }
            } else {
                if (value) {
                    const params = {
                        arId: arListData.value! && arListData.value[0].id,
                        alrId: 0,
                        acrList: [
                            {
                                componentId: item.componentId,
                                result: ''
                            }
                        ]
                    }
                    if (Array.isArray(value)) {
                        const newValue = _.cloneDeep(value);
                        if (item.type === 'checkbox' || item.type === 'child_select') {
                            params.acrList[0].result = newValue.length > 1 ? newValue.join('@#@') : newValue[0];
                        } 
                    } else {
                        params.acrList[0].result = value;
                    }
                    if (type === 2 && currentSubmenuItem) {
                        params.alrId = Number(currentSubmenuItem);
                    }
                    const res = await saveCrListData(params);
                    const { acrList } = res.data;
                    item.acrId = acrList[0].acrId;
                    item.id = acrList[0].acrId;
                    Message.success('新增成功！');
                    // getInitData();
                }
            }
        }
    };

    // 设置初始时病灶配置
    const lesionSettings = ref<Type.LesionItem[] | null>([]);

    // 设置初始时组件数据
    const seriesSetData = ref<Type.SeriesItem[] | null>([]);

    // 任务名称及序列号
    const showTaskName = ref<string>('');
    const seriesUid = ref<string>('');
    const newResultData = reactive<{[key: string | number]: string | number}>({});

    // 初始获取标注序列 根据序列处理后续加载大图，标注工具，征象操作
    const initCommonData = async () => {
        // 清除本地尺子缓存
        localStorage.removeItem('markData');
        // 获取任务id
        const { id } = route.query;
        const params: Type.TaskParams = { taskId: Number(id) };
        // 得到初始化的标注序列
        const arListRes = await getAnnoArList(params);
        arListData.value = arListRes.data?.arList!;
        seriesUid.value = arListData?.value[0]?.seriesUid;
        const lesionParams = {
            page: 1,
            pageSize: 1000000
        }
        const res = await searchLesionData(lesionParams);
        const resultData = res?.data?.list;
        resultData?.map((item: { value: string | number; name: any; }) => {
            newResultData[item.value] = item.name;
        })
        // 得到初始化的配置数据
        const settingsRes = await getInitSettingData(params);
        if (!settingsRes) return;
        const { 
            taskName = '',
            seriesCompList = [], 
            lesionList = [], 
            discardCodeList = '', 
            defaultWindow = '', 
            findings = false, 
            diagnosis = false, 
            showYay = false, 
            showReport = false, 
            imageLayout = '' 
        } = settingsRes?.data;
        // 任务名称处理
        showTaskName.value = taskName;
        // 大征象处理
        seriesCompList && (seriesSetData.value = seriesCompList);
        // 根据大征象数据处理获取详细配置名单
        getSeriesCompData(seriesSetData.value, seriesSettings.value);
        // 病灶处理
        lesionList && (lesionSettings.value = getLesionName(lesionList, newResultData));
        // 根据病灶数据获取详细配置名单 并同步处理小征象（标注征象）逻辑
        getMarkLesionData();
        // 废片原因处理
        discardCodeList && (scrapValue.value = discardCodeList);
        // 窗宽窗位
        // 检查所见是否展示
        findings && (findingVisible.value = findings);
        // 诊断所得是否展示
        diagnosis && (diagnosisVisible.value = diagnosis);
        // 阴阳性是否展示
        showYay && (radioVisible.value = showYay);
        // 图文报告是否展示
        // 布局分类
        // 初始加载大图容器
        initViewer();
        // 操作查看工具及标注工具
        handleChangeToolViewer();
        // 初始化创建标注工具
        initMarkTool();
        // 获取大图相关信息
        slideInfo.value = getInfo();
        // 初始获取相应倍率进行数值展示
        initZoom();
        // 校正canvas标注画布
        // resizeCanvas();
        // 绑定监听事件用于大图渲染校正canvas标注画布
        viewer.value?.addHandler("update-viewport", resizeCanvas);
        viewer.value?.addHandler("open", resize);
        viewer.value?.addHandler("resize", resize);
        console.log(window.frabicCanvas.calcOffset().viewportTransform, '修正');
        // 初始化回显数据
        // setTimeout(() => {
            getInitData();
        // }, 100)
    };

    // 获取病灶名称
    const getLesionName = (dataList: Type.LesionItem[], newResultData: { [x: string]: string | number; }) => {
        dataList = dataList.map(item => {
            item.name = String(newResultData[item.lesion]);
            return item;
        })
        return dataList;
    }

    // 获取征象组件
    const getSeriesCompData = (dataList: Type.SeriesItem[] | null, result: Temp.ShowComponentObj) => {
        dataList?.map(async (item: { componentId: number; required: boolean; }) => {
            const res = await formComponentRead(item.componentId);
            if (!res.data) return;
            const { code, id, name, type, parameter, data, ...newRes } = res.data;
            const tempParameter = JSON.parse(parameter || '{}');
            const tempObj: Temp.FormOptionsItem = {
                id: 0,
                componentId: 0,
                title: '',
                field: '',
                type: '',
                required: false
            };
            if (type === 'checkbox') {
                result && (result.form[code] = []);
            } else {
                result && (result.form[code] = '');
            }
            if (tempParameter.isdefault) {
                // 为true要调用新增征象接口
            }
            tempObj.id = id;
            tempObj.componentId = item.componentId;
            tempObj.title = name;
            tempObj.field = code;
            tempObj.type = type;
            tempObj.required = item.required;
            tempObj.parameter = tempParameter;
            tempObj.data = getOptionData(JSON.parse(data || '[]'));
            result && result.formOptions.push(tempObj);
        })
    };

    // 递归处理级联菜单
    const getOptionData = (dataList: any[]) => {
        if (!dataList) return [];
        dataList = dataList.map((item: { child: any[]; code: string; text: string; }) => {
            let obj = {
                value: '',
                label: '',
                children: <any[]>[]
            };
            if (item.child && item.child.length > 0) {
                obj.value = item.code;
                obj.label = item.text;
                obj.children = getOptionData(item.child);
            } else {
                obj.value = item.code;
                obj.label = item.text;
            }
            return obj;
        })
        return dataList;
    };

    // 处理标注工具下的病灶列表数据及同步处理小征象（标注征象）
    const getMarkLesionData = () => {
        // 初始化时重置掉mark前端设定的list模板
        markList.value = markList.value?.map(item => {
            item.nidusList = [];
            return item;
        });
        lesionSettings.value?.map(item => {
            if(item.toolList?.some(it => it === 'RECTANGLE')){
                const tempArr = markList.value?.filter(it => it.type === (item.toolList?.find(v => v === 'RECTANGLE')));
                const { imageCompList, ...newItem } = item;
                const tempObj = {
                    ...newItem,
                    eyeStatus: true,
                    list: {
                        formId: 0,
                        form: {},
                        formOptions: []
                    }
                };
                getSeriesCompData(item.imageCompList, tempObj.list);
                tempArr[0]?.nidusList.push(tempObj);
            }
            if(item.toolList?.some(it => it === 'ELLIPSE')){
                const tempArr = markList.value?.filter(it => it.type === (item.toolList?.find(v => v === 'ELLIPSE')));
                const { imageCompList, ...newItem } = item;
                const tempObj = {
                    ...newItem,
                    eyeStatus: true,
                    list: {
                        formId: 0,
                        form: {},
                        formOptions: []
                    } 
                };
                getSeriesCompData(item.imageCompList, tempObj.list);
                tempArr[0]?.nidusList.push(tempObj);
            }
        })
    };

    // 数据回显获取大征象组件数据
    const getSeriesCompResultData = (dataList: Type.SeriesResultItem[] | null,) => {
        // 根据结果数据转换成相应实际结果
        dataList?.map(async (item) => {
            const res = await formComponentRead(item.componentId);
            const { code, id, name, type, parameter, data, ...newRes } = res.data;
            if (item.componentId === id) {
                if (type === 'checkbox' || type === 'child_select') {
                    typeof item.result === 'string' && (item.result = item.result.split('@#@'));
                }
                seriesSettings.value.form[code] = item.result;
                seriesSettings.value.formOptions.map(it => {
                    if (it.componentId === item.componentId) {
                        it.acrId = item.id;
                    }
                    it.id = item.id;
                })
            }
        })
    };
    const currentLesionTemp = {
        id: 0,
        name: '',
        lesion: '',
        color: '',
        eyeStatus: true,
        toolList: [''],
        list: {
            formId: 0,
            form: <any>{},
            formOptions: <any[]>[]
        }
    }
    // 数据回显病灶数据回显
    const getLesionData = (dataList: Type.LesionResultItem[], type: boolean = false) => {
        showLesionList.value = [];
        dataList.map(item => {
            const { id, color, lesion, tool, resultType, result, imageCompResultList } = item;
            const currentLesion = _.cloneDeep(currentLesionTemp);
            currentLesion.id = id;
            currentLesion.lesion = lesion;
            currentLesion.name = String(newResultData[lesion]);
            currentLesion.color = color;
            currentLesion.toolList = new Array(tool);
            markList.value.map(ite => {
                if (ite.type === tool) {
                    ite.nidusList.map(v => {
                        if (v.lesion === lesion) {
                            currentLesion.list = _.cloneDeep(v.list);
                        }
                    })
                }
            })
            if (imageCompResultList?.length !== 0) {
                imageCompResultList?.map(async (it) => {
                    const res = await formComponentRead(it.componentId);
                    const { code, id: sId, name, type, parameter, data, ...newRes } = res.data;
                    currentLesion.list.formOptions.map(t => {
                        if (t.componentId === it.componentId) {
                            t.acrId = it.id;
                            t.id = it.id;
                        }
                    })
                    if (type === 'checkbox' || type === 'child_select') {
                        typeof it.result === 'string' && (it.result = it.result.split('@#@'));
                    }
                    currentLesion.list.form[code] = it.result;
                })
            }
            console.log(window.frabicCanvas.calcOffset().viewportTransform, 'set');
            const showLesionObj = {
                disease: { ...currentLesion },
                // 循环内处理每一个非line模式的fabric对象
                markInfo: getMarkCanvasObj(tool, id, color, result, viewer, slideInfo, fabricCanvas)
            }
            
            // 数据回显
            showLesionList.value.push(showLesionObj);
        })
        // 尺子回显
        const note = JSON.parse(localStorage.getItem('markData') || '{}');
        if (note) {
            // 处理倍率
            note.objects = note.objects?.map((item: any) => {
                getLocalStroage(item, viewer, fabricCanvas, slideInfo);
            })
            // currentItem.value = 0;
        }
        // 新增画完标注聚焦
        if(type) {
            getActiveObject();
        }
    };

    // 挂载阶段初始化执行获取配置函数及数据渲染
    onMounted(() => {
        initCommonData();
    });
    
    return {
        viewerRef,
        viewer,
        multiplying,
        currentItem,
        handleToolClick,
        handleMagnification,
        menuItemVisibile, 
        eyeAllVisibile, 
        handleEyeClick, 
        handleAllEyeClick, 
        handleDelClick,
        handleColorChange,
        getActualNum,
        arListData,
        fabricToolCanvas, 
        fabricCanvas,
        getInitData,
        handleChange,
        showTaskName,
        seriesUid,
        mouseString,
        handleMouseMove
    };
};